#include "filereader.h"

/**
 * 01.03.12 - Steven Hartin - Original file creation
 */

CFileReader::CFileReader(const string &szFilePath) :
    m_szFilePath(szFilePath)
{
    /**
     * Constructor, ensure that the file path is readable and open the file.
     *
     * @param string szFilePath The path of the file to read
     */ 
    _openFile();
}

CFileReader::CFileReader() :
    m_szFilePath("")
{
    /**
     * Constructor, ensure that the file path is set to nothing.
     */ 
}

void CFileReader::setFilePath(const string &szFilePath)
{
    /**
     * Sets the file path to a string file path and attempts to open the file.
     *
     * @param const string &szFilePath The path of the file to open.
     */
    m_szFilePath = szFilePath;
    _openFile();
}

CFileReader::~CFileReader()
{
    /**
     * Destructor, ensrue that any open file handle is closed.
     */
    _closeFile();
}

void CFileReader::_openFile()
{
    /**
     * Opens the file stream and stores it in the file stream.
     *
     * Does no checking for overwriting files etc.
     */
    m_FileStream.exceptions(ifstream::failbit | ifstream::badbit );
    m_FileStream.open(m_szFilePath, std::ios::in | std::ios::binary);
}

void CFileReader::_closeFile()
{
    /**
     * If the file is open, closes the file stream to ensure no file
     * handles are left open.
     */
    if (m_FileStream.is_open())
    {
        m_FileStream.close();
    }
}

short int CFileReader::readShort()
{
    /**
     * reads a short to the file stream assuming that the stream is open.
     *
     * @param short int nValue The value to read to the stream
     */
    if (m_FileStream.is_open())
    {
        char chInput[sizeof(short int)];
        m_FileStream.read(chInput, sizeof(short int));
        short int *pValue(reinterpret_cast<short int*>(chInput));
        return *pValue;
    }
    return 0;
}

long int CFileReader::readLong()
{
    /**
     * reads a long to the file stream assuming that the stream is open.
     *
     * @param long int nValue The value to read to the stream
     */
    if (m_FileStream.is_open())
    {
        char chInput[sizeof(long int)];
        m_FileStream.read(chInput, sizeof(long int));
        long int *pValue(reinterpret_cast<long int*>(chInput));
        return *pValue;
    }
    return 0;
}

bool CFileReader::readBool()
{
    /**
     * reads a short to the file stream assuming that the stream is open.
     *
     * @param bool bValue The value to read to the stream
     */
    if (m_FileStream.is_open())
    {
        char chInput[sizeof(bool)];
        m_FileStream.read(chInput, sizeof(bool));
        bool *pValue(reinterpret_cast<bool*>(chInput));
        return *pValue;
    }
    return false;
}

string CFileReader::readString(int nCount)
{
    /**
     * reads a short to the file stream assuming that the stream is open.
     *
     * @param const string &szValue The value to read to the stream
     */
    if (m_FileStream.is_open())
    {
        // Max size we can read is 100 bytes
        char pChar[100];
        m_FileStream.read(pChar, nCount * sizeof(char));
        pChar[nCount] = '\0';
        return string(pChar);
    }
    return string("");
}

char CFileReader::readChar()
{
    /**
     * reads a short to the file stream assuming that the stream is open.
     *
     * @param char chValue The value to read to the stream
     */
    if (m_FileStream.is_open())
    {
        char chInput[sizeof(char)];
        m_FileStream.read(chInput, sizeof(char));
        char *pValue(reinterpret_cast<char*>(chInput));
        return *pValue;
    }
    return '\0';
}

float CFileReader::readFloat()
{
    /**
     * reads a short to the file stream assuming that the stream is open.
     *
     * @param float fValue The value to read to the stream
     */
    if (m_FileStream.is_open())
    {
        char chInput[sizeof(float)];
        m_FileStream.read(chInput, sizeof(float));
        float *pValue(reinterpret_cast<float*>(chInput));
        return *pValue;
    }
    return 0.0f;
}

double CFileReader::readDouble()
{
    /**
     * reads a short to the file stream assuming that the stream is open.
     *
     * @param double dValue The value to read to the stream
     */
    if (m_FileStream.is_open())
    {
        char chInput[sizeof(double)];
        m_FileStream.read(chInput, sizeof(double));
        double *pValue(reinterpret_cast<double*>(chInput));
        return *pValue;
    }
    return 0.0;
}

ENTITY_ID CFileReader::readEntityId()
{
    /**
     * Reads an entity ID from the file assuming the stream is open.
     *
     * @return ENTITY_ID The ID of the file read in.
     */
    if (m_FileStream.is_open())
    {
        char chInput[sizeof(ENTITY_ID)];
        m_FileStream.read(chInput, sizeof(ENTITY_ID));
        ENTITY_ID *pValue(reinterpret_cast<ENTITY_ID*>(chInput));
        return *pValue;
    }
    return ENT_NONE;
}